#include "ModbusSlave_Task.h"
#include "74HC595.h"
#include "Output.h"
#include "modbus.h"

void ModbusSlave_Task(void* pdata) {
    Sys_Base.para.slave_id = Get_Slaveid();   // 从机地址获取，默认2
    Sys_Base.version       = 0x01;            // 版本号
    for (;;) {
        WaitUartIdle(UART1_CON, 0);
        Modbus_action();
        OSTimeDly(100);
    }
}

static ModbusSlave_DataStructTypedef DataList[] = {
    {0x0000, ModbusSlave_RW, &Sys_Base.para.slave_id, 1, Set_Slave_id, NULL},   // 从机地址
    {0x0001, ModbusSlave_RW, &Sys_Base.para.type, 1, Sys_para_save, NULL},      // 模块类型
    {0x0002, ModbusSlave_RW, &Sys_Base.para.mod_num, 1, Sys_para_save, NULL},   // 扩展模块数
    {0x0003, ModbusSlave_RW, &Sys_Base.run_state, 1, NULL, NULL},               // 工作状态
    {0x0004, ModbusSlave_RW, &Sys_Base.ctrl_state, 1, Reset_System, NULL},      // 控制状态
    {0x0005, ModbusSlave_RW, &Sys_Base.version, 1, NULL, NULL},                 // 控制状态

    {0x01F4, ModbusSlave_RW, &Relay.alarm_relay[0], 1, Alarm_Output, 0},   // 报警输出状态
    {0x01F5, ModbusSlave_RW, &Relay.alarm_relay[1], 1, Alarm_Output, 1},   // 报警输出状态

    {0x01F6, ModbusSlave_RW, &Relay.base_relay[0], 1, Relay_Output, 1},     // 继电器输出状态
    {0x01F7, ModbusSlave_RW, &Relay.base_relay[1], 1, Relay_Output, 2},     //
    {0x01F8, ModbusSlave_RW, &Relay.base_relay[2], 1, Relay_Output, 3},     //
    {0x01F9, ModbusSlave_RW, &Relay.base_relay[3], 1, Relay_Output, 4},     //
    {0x01FA, ModbusSlave_RW, &Relay.base_relay[4], 1, Relay_Output, 5},     //
    {0x01FB, ModbusSlave_RW, &Relay.base_relay[5], 1, Relay_Output, 6},     //
    {0x01FC, ModbusSlave_RW, &Relay.base_relay[6], 1, Relay_Output, 7},     //
    {0x01FD, ModbusSlave_RW, &Relay.base_relay[7], 1, Relay_Output, 8},     //
    {0x01FE, ModbusSlave_RW, &Relay.base_relay[8], 1, Relay_Output, 9},     //
    {0x01FF, ModbusSlave_RW, &Relay.base_relay[9], 1, Relay_Output, 10},    //
    {0x0200, ModbusSlave_RW, &Relay.base_relay[10], 1, Relay_Output, 11},   //
    {0x0201, ModbusSlave_RW, &Relay.base_relay[11], 1, Relay_Output, 12},   //
    {0x0202, ModbusSlave_RW, &Relay.base_relay[12], 1, Relay_Output, 13},   //
    {0x0203, ModbusSlave_RW, &Relay.base_relay[13], 1, Relay_Output, 14},   //
    {0x0204, ModbusSlave_RW, &Relay.base_relay[14], 1, Relay_Output, 15},   //
    {0x0205, ModbusSlave_RW, &Relay.base_relay[15], 1, Relay_Output, 16},   //
    {0x0206, ModbusSlave_RW, &Relay.base_relay[16], 1, Relay_Output, 17},   //
    {0x0207, ModbusSlave_RW, &Relay.base_relay[17], 1, Relay_Output, 18},   //
    {0x0208, ModbusSlave_RW, &Relay.base_relay[18], 1, Relay_Output, 19},   //
    {0x0209, ModbusSlave_RW, &Relay.base_relay[19], 1, Relay_Output, 20},   //
    {0x020A, ModbusSlave_RW, &Relay.base_relay[20], 1, Relay_Output, 21},   //
    {0x020B, ModbusSlave_RW, &Relay.base_relay[21], 1, Relay_Output, 22},   //
    {0x020C, ModbusSlave_RW, &Relay.base_relay[22], 1, Relay_Output, 23},   //
    {0x020D, ModbusSlave_RW, &Relay.base_relay[23], 1, Relay_Output, 24},   //
    {0x020E, ModbusSlave_RW, &Relay.base_relay[24], 1, Relay_Output, 25},   //
    {0x020F, ModbusSlave_RW, &Relay.base_relay[25], 1, Relay_Output, 26},   //
    {0x0210, ModbusSlave_RW, &Relay.base_relay[26], 1, Relay_Output, 27},   //
    {0x0211, ModbusSlave_RW, &Relay.base_relay[27], 1, Relay_Output, 28},   //
    {0x0212, ModbusSlave_RW, &Relay.base_relay[28], 1, Relay_Output, 29},   //
    {0x0213, ModbusSlave_RW, &Relay.base_relay[29], 1, Relay_Output, 30},   //
    {0x0214, ModbusSlave_RW, &Relay.base_relay[30], 1, Relay_Output, 31},   //
    {0x0215, ModbusSlave_RW, &Relay.base_relay[31], 1, Relay_Output, 32},   //
    {0x0216, ModbusSlave_RW, &Relay.base_relay[32], 1, Relay_Output, 33},   //
    {0x0217, ModbusSlave_RW, &Relay.base_relay[33], 1, Relay_Output, 34},   //
    {0x0218, ModbusSlave_RW, &Relay.base_relay[34], 1, Relay_Output, 35},   //
    {0x0219, ModbusSlave_RW, &Relay.base_relay[35], 1, Relay_Output, 36},   //
    {0x021A, ModbusSlave_RW, &Relay.base_relay[36], 1, Relay_Output, 37},   //
    {0x021B, ModbusSlave_RW, &Relay.base_relay[37], 1, Relay_Output, 38},   //

    {0x0258, ModbusSlave_RW, &Emer.enable, 1, NULL, NULL},                           // 应急风机功能状态
    {0x0259, ModbusSlave_RW, &Sys_Base.para.target_temp, 1, Sys_para_save, NULL},    // 目标温度
    {0x025A, ModbusSlave_RW, &Sys_Base.para.start_dif[0], 1, Sys_para_save, NULL},   // 应急风机1启动偏差
    {0x025B, ModbusSlave_RW, &Sys_Base.para.start_dif[1], 1, Sys_para_save, NULL},   // 应急风机2启动偏差
    {0x025C, ModbusSlave_RW, &Sys_Base.para.High_temp, 1, Sys_para_save, NULL},      // 高温报警偏差
    {0x025D, ModbusSlave_RW, &Sys_Base.para.Low_temp, 1, Sys_para_save, NULL},       // 低温报警偏差

    {0x02BC, ModbusSlave_RW, &Sys_Base.run_state, 1, NULL, NULL},     // 工作状态
    {0x02BD, ModbusSlave_RW, &Sys_Base.alarm_state, 1, NULL, NULL},   // 报警状态
    {0x02BE, ModbusSlave_RW, &Power.vol, 1, NULL, NULL},              // 电池电压
    {0x02BF, ModbusSlave_RW, &Sensor.temp_avg, 1, NULL, NULL},        // 平均温度
    {0x02C0, ModbusSlave_RW, &Sensor.temp[0], 1, NULL, NULL},         // 温度1
    {0x02C1, ModbusSlave_RW, &Sensor.temp[1], 1, NULL, NULL},         // 温度2

};
void Task_ModbusSlave_Init(void) {
    ModbusSlave_Init(DataList, (sizeof(DataList) / sizeof(DataList[0])));
}

uint8_t Set_Slave_id(uint16_t addr, uint8_t cmd, uint16_t length, uint8_t* data, uint32_t para) {
    if (cmd != 0x03) {
        Set_Slaveid(Sys_Base.para.slave_id);
    }
    return 1;
}

uint8_t Reset_System(uint16_t addr, uint8_t cmd, uint16_t length, uint8_t* data, uint32_t para) {
    if (cmd != 0x03 && Sys_Base.ctrl_state == 1) {
        SystemReset();
    }
    return 1;
}
uint8_t Alarm_Output(uint16_t addr, uint8_t cmd, uint16_t length, uint8_t* data, uint32_t para) {
    uint16_t value;
    value = *data++;
    value <<= 8;
    value |= *data++;
    if (cmd != 0x03) {
        Output_Control(para, value);
    }

    return 1;
}

uint8_t Relay_Output(uint16_t addr, uint8_t cmd, uint16_t length, uint8_t* data, uint32_t para) {
    uint16_t value;
    value = *data++;
    value <<= 8;
    value |= *data++;
    if (cmd != 0x03) {
        JDQ_Control(para, value);
    }

    return 1;
}
uint8_t Sys_para_save(uint16_t addr, uint8_t cmd, uint16_t length, uint8_t* data, uint32_t para) {
    if (cmd != 0x03) {
        SPI_Flash_Write((INT8U*) &Sys_Base.para.slave_id, para_data_addr, sizeof(Sys_Base.para));
    }
    return 1;
}
